home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / dev / sun4.md / devJaguarHBA.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  57KB  |  1,870 lines

  1. /* 
  2.  * devJaguarHBA.c --
  3.  *
  4.  *    Driver for the Interphase V/SCSI 4210 Jaguar SCSI host bus adapter 
  5.  *    for SUN's running Sprite.
  6.  *
  7.  * Copyright 1989 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/dev/sun4.md/devJaguarHBA.c,v 9.10 92/10/23 15:03:42 elm Exp $ SPRITE (Berkeley)";
  18. #endif /* not lint */
  19.  
  20. #include <sprite.h>
  21. #include <mach.h>
  22. #include <jaguar.h>
  23. #include <jaguarDefs.h>
  24. #include <dev.h>
  25. #include <devInt.h>
  26. #include <sys/scsi.h>
  27. #include <scsiHBA.h>
  28. #include <scsiDevice.h>
  29. #include <vmMach.h>
  30. #include <sync.h>
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <bstring.h>
  35.  
  36. /*
  37.  * WARNING -- WARNING --- WARNING --- WARNING
  38.  * The code and data structures in this file are carefully coded to 
  39.  * run on machines that don't do autobus sizing and unaligned memory fetches.
  40.  *
  41.  * Please keep in mind the following:
  42.  *
  43.  * 1) Although structures like struct JaguarMem appear to be C data structures
  44.  *    they are used to describe the interface to the Jaguar controller board.
  45.  *    Because these data structures need to be understood by both the
  46.  *    host CPU and the Jaguar's processor changes should only occur when
  47.  *    the Jaguar's firmware changes the interface. 
  48.  * 2) The Jaguar is accessed in the short IO spaces on the VME bus. This
  49.  *    means that the data path is only 16 bits wide. This means that
  50.  *    unless your processor does autobus sizing (ie convert 32 bit accesses
  51.  *    into 2 16 bit access if the bus width is 16 bit) only shorts should
  52.  *    be stored into JaguarMem. Note: SPARC (the sun4) doesn't do autobus
  53.  *    sizing.
  54.  * 3) Beware of padding introduced by the compiler. For example, if the
  55.  *    Jaguar documentation says:
  56.  *      2 bytes length
  57.  *      4 bytes buffer address
  58.  *    and you declare a C structure to be 
  59.  *       struct {
  60.  *        short length;
  61.  *        char  *bufAddr;
  62.  *     }
  63.  *    Things will break (on sun4) because the compiler will added 2 bytes of
  64.  *    padding to insure that the (char *) starts on the (4 byte) word boundry.
  65.  *    The routine CheckSizes in this file tries to catch errors of this 
  66.  *    form.
  67.  */
  68.  
  69. /*
  70.  * The Jaguar occupies 2 Kbytes on the VME short I/O space (DEV_VME_D16A16).
  71.  * The image of these 2 Kbytes is described by the structure 
  72.  * struct JaguarMem. Some of the members of this structure like 
  73.  * the mcsb, mce, cmdQueue,and css must occur at fixed offsets from the start
  74.  * of the 2K region. The other items in JaguarMem are placed at fixed offsets
  75.  * to simplify the driver and may be moved around.
  76.  */
  77.  
  78. /*
  79.  * Constants that define the layout of JaguarMem.
  80.  *
  81.  * SIZE_JAUGAR_MEM - The size of the dual ported memory accessible to the
  82.  *             host.
  83.  * NUM_CQE       -  Number of entries in the command queue. This limits
  84.  *                  the number of unacknowledged commands that we can submit
  85.  *                 to the Jaguar. For a lack of a better number, 8.
  86.  *
  87.  * NUM_SG_ELEMENTS - Number of scatter/gather elements allocated in the 
  88.  *             juguar memory.  Scatter/gather elements don't needed
  89.  *             to be allocated in Jaguar memory but it is convenient
  90.  *             to do so.  Otherwise they would have to be allocated
  91.  *             or mapped into DVMA space.
  92.  *
  93.  * MEM_PAD           Number of bytes of free space not allocated in the
  94.  *                  structure JaguarMem. Note that MEM_PAD is a function 
  95.  *                 of NUM_SG_ELEMENTS and NUM_CQE.
  96.  * NUM_WORK_QUEUES   Number of work queues to use. 
  97.  * 
  98.  */
  99.  
  100. #define    SIZE_JAUGAR_MEM    (2*1024)
  101. #define    NUM_CQE 8
  102. #define    NUM_SG_ELEMENTS    64
  103. #define    NUM_WORK_QUEUES    14
  104.  
  105. #define    MEM_PAD (SIZE_JAUGAR_MEM - sizeof(JaguarMCSB) -  \
  106.         (NUM_CQE+1)*(sizeof(JaguarIOPB)+sizeof(JaguarCQE)) - \
  107.         sizeof(JaguarCRB) - sizeof(JaguarCCSB) - \
  108.         NUM_SG_ELEMENTS * sizeof(JaguarSG))
  109.  
  110. typedef struct JaguarMem {
  111.     JaguarMCSB    mcsb;    /* Master Control and Status Block. 16 Bytes  */
  112.     JaguarCQE    mce;    /* Master Command Entry Queue. 12 Bytes */
  113.     JaguarCQE    cmdQueue[NUM_CQE]; /* Command Queue. 12*NUM_CQE Bytes */
  114.     JaguarIOPB    masterIOPB;    /* IOPB used for the MCE. 64 Bytes */
  115.     JaguarIOPB    iopbs[NUM_CQE]; /* IOPB for cmdQueue. 64*NUM_CQE Bytes*/
  116.     JaguarSG    sgElements[NUM_SG_ELEMENTS];
  117.                     /* Scatter/gather elements for host. */
  118.     char        padding[MEM_PAD]; /* Padding to force css field into
  119.                        * correct offset. */
  120.     JaguarCRB    crb;    /* Command response block. 76 Bytes */
  121.     JaguarCCSB    css;    /* Contoller specific Space. 120 Bytes */
  122. } JaguarMem;
  123.  
  124. /*
  125.  * Many of the Jaguar's data structures need addresses as offsets into the
  126.  * JaguarMem. To deal with this offsets:
  127.  *
  128.  * POINTER_TO_OFFSET()    - Convert a host pointer to an offset.
  129.  * OFFSET_TO_POINTER()    - Convert an offset to a host pointer.
  130.  *
  131.  */
  132. #define    POINTER_TO_OFFSET(ptr, memPtr)    ((unsigned)(ptr) - (unsigned)(memPtr))
  133. #define OFFSET_TO_POINTER(offset, memPtr) ((char *)(memPtr)+(unsigned)(offset))
  134.  
  135. /* 
  136.  * workq (s) - 
  137.  * From the documentation it appears that for the Jaguar to  efficiently 
  138.  * talk to a device a workq must be configured for the device.  The 
  139.  * documentation doesn't mention a cost associated with having many 
  140.  * unused workq so it is tempting to create all 14 work queues at 
  141.  * initialization time.  The reason for not doing this is that certain
  142.  * options such as parity and workq priority is determined during
  143.  * work queue initialization. 
  144.  * 
  145.  */
  146. /* Forward declaration. */
  147. typedef struct Controller Controller;
  148.  
  149. /*
  150.  * Device - The data structure containing information about a device. One of
  151.  * these structure is kept for each attached device. Note that is structure
  152.  * is casted into a ScsiDevice and returned to higher level software.
  153.  * This implies that the ScsiDevice must be the first field in this
  154.  * structure.
  155.  */
  156.  
  157. typedef struct Device {
  158.     ScsiDevice handle;    /* Scsi Device handle. This is the only part
  159.              * of this structure visible to higher 
  160.              * level software. MUST BE FIRST FIELD IN STRUCTURE. */
  161.     int    bus;        /* Bus number of device. */
  162.     int    targetID;    /* TargetID of device. */
  163.     int    unitAddress;    /* Jaguar address of this device.  */
  164.     int    workQueue;    /* Jaguar workqueue allocated for this device. */
  165.     int    numActiveCmds;    /* Number of commands enqueued on the HBA for this
  166.              * command. */
  167.     Controller  *ctrlPtr; /* Controller to which device is attached. */
  168.            /*
  169.             * The following part of this structure is 
  170.             * used to handle SCSI commands that return 
  171.             * CHECK status. To handle the REQUEST SENSE
  172.             * command we must: 1) Save the state of the current
  173.             * command into the "struct FrozenCommand". 2) Submit
  174.             * a request sense command  */
  175.  
  176.     struct FrozenCommand {               
  177.     ScsiCmd    *scsiCmdPtr;       /* The frozen command. */
  178.     unsigned char statusByte; /* It's SCSI status byte, Will always have
  179.                    * the check bit set. */
  180.     int amountTransferred;    /* Number of bytes transferred by this 
  181.                    * command. */
  182.     } frozen;    
  183. } Device;
  184.  
  185. typedef struct CmdAction {
  186.     int    action;        /* Action to be performed when command completes. 
  187.              * See below for list of actions. */
  188.     int        dmaBufferLen;    /* DMA buffer length. */
  189.     Address    dmaBuffer; /* DMA buffer for device. */
  190.     ClientData    actionArg;    /* Argument for action. */
  191. } CmdAction;
  192.  
  193. /*
  194.  * Upon command termination. The interrupt handler can be instructed to
  195.  * perform serveral possible actions.
  196.  *
  197.  * UNUSED_ACTION -     This action buffer is used.
  198.  * FILL_IN_CRB_ACTION - Fill in the specified pointer with the completion
  199.  *            CRB.
  200.  * SCSI_CMD_ACTION -    This command is a SCSI command. Invoke RequestDone
  201.  *            function.
  202.  * IS_WAIT_ACTION() -   TRUE if the action requires the command to be
  203.  *            executed synchronously.
  204.  * NUM_ACTIONS        -   Number of action buffers to allocate per controller.
  205.  *            This number must be creater than the number of 
  206.  *            devices * the number of queued commands.
  207.  */
  208. #define    UNUSED_ACTION        0x0
  209. #define    FILL_IN_CRB_ACTION    0x1
  210. #define    SCSI_CMD_ACTION        0x2
  211.  
  212. #define    IS_WAIT_ACTION(action)    ((action)== FILL_IN_CRB_ACTION)
  213. #define    NUM_ACTIONS        64
  214. /*
  215.  * Controller - The Data structure describing a Jaguar controller. One
  216.  * of these structures exists for each active Jaguar HBA on the system. Each
  217.  * controller may have from zero to 14 devices attached to it. 
  218.  */
  219. struct Controller {
  220.     volatile JaguarMem *memPtr;    /* Pointer to the registers
  221.                                     of this controller. */
  222.     volatile JaguarCQE *nextCQE; /* Next available CQE. */
  223.     Boolean workQueue0Busy; /* Work Queue 0 is being used. */
  224.     char    *name;    /* String for error message for this controller.  */
  225.     Sync_Semaphore mutex; /* Lock protecting controller's data structures. */
  226.     DevCtrlQueues devQueues;    /* Device queues for devices attached to this
  227.                  * controller.     */
  228.     Sync_Condition ctrlCmdWait; /* Wait condition for syncronous command
  229.                  * to finish. */
  230.     Sync_Condition ctrlQueue0Wait; /* Wait condition for exclustive access
  231.                     * to workqueue 0. */
  232.     int        intrLevel;    /* VME interrupt level for controller. */
  233.     int        intrVector;    /* VME interrupt vector for controller in
  234.                  * the format expected by the Jaguar. */
  235.     int        nextActionBuffer; /* Next cmdAction buffer to allocated. */
  236.     CmdAction    cmdAction[NUM_ACTIONS]; /* Action to be performed when command 
  237.                          * completes. */
  238.     Device  *devices[NUM_WORK_QUEUES];   /* Pointers to the device attached. The
  239.                      * index is the workQueue number - 1. */
  240. };
  241.  
  242. #define MAX_JAGUAR_CTRLS    16
  243. static Controller    *Controllers[MAX_JAGUAR_CTRLS];
  244.  
  245.  
  246. static int    devJaguarDebug = 0;
  247.  
  248. /*
  249.  * The follow data structure is used by the Sprite kernel debugger to 
  250.  * examine Jaguar memory. See routine GetJaguarMem.
  251.  */
  252. #ifndef lint
  253. static JaguarMem DebugJaguarMem;
  254. #endif
  255. /*
  256.  * Constants for the sun implementation.
  257.  * DMA_BURST_COUNT - The number of VME DMA transfers performed in a 
  258.  *             single burst before releasing the bus.  A value of
  259.  *             0 uses the maximum of 128 32-bit transfers.
  260.  * JAGUAR_WORD_ADDRESS_MODIFIER
  261.  * JAGUAR_BLOCK_ADDRESS_MODIFIER - The Address space modifier and transfer type
  262.  *                 for Jaguar DMA. We choose 32 bit normal mode
  263.  *                 transfers with a A24 bit supervisor data address
  264.  *                 modifier (0x3d or 0x3f).
  265.  * MAX_CMDS_QUEUED - Maximum number of command to queue per device.
  266.  * SELECTION_TIMEOUT - Timeout value for selecting a device in 1 millisecond
  267.  *               ticks. We choose 1 second timeout.
  268.  * RESELECTION_TIMEOUT - Timeout value for a device re-selecting in 32 
  269.  *             milliseconds ticks. 0 means infinite.  
  270.  * VME_TIMEOUT - Timeout value for VME access. 0 means 100 milliseconds.
  271.  * DEV_MAX_DMA_SIZE - Maximum size of a DMA request to this device.
  272.  */
  273.  
  274. #define    DMA_BURST_COUNT        0
  275. #define    JAGUAR_WORD_ADDRESS_MODIFIER  (JAGUAR_32BIT_MEM_TYPE | \
  276.                   JAGUAR_NORMAL_MODE_XFER | 0x0d)
  277. #define    JAGUAR_BLOCK_ADDRESS_MODIFIER  (JAGUAR_32BIT_MEM_TYPE | \
  278.                   JAGUAR_BLOCK_MODE_XFER | 0x0f)
  279. #define    MAX_CMDS_QUEUED        2
  280. #define    SELECTION_TIMEOUT    1000
  281. #define    RESELECTION_TIMEOUT    0
  282. #define    VME_TIMEOUT        0
  283. #define    DEV_MAX_DMA_SIZE    (128*1024)
  284. #define    VME_INTERRUPT_PRIORITY    3    /* was 2, changed by elm */
  285.  
  286.  
  287. /*
  288.  * Macros for reading and writing 32 bit values from the short IO space.
  289.  */
  290.  
  291. #define    READ_LONG(var)    (((var)[0]<<16)|((var)[1]))
  292. #define    SET_LONG(var,value) \
  293.         (((var)[0] = ((value)>>16)),((var)[1]=(0xffff&(value))))
  294.  
  295. static void LockWorkq0();
  296. static void UnLockWorkq0();
  297. static void CopyFromJaguarMem();
  298. static void CopyToJaguarMem();
  299. static void ZeroJaguarMem();
  300. static Boolean WaitForBitSet();
  301. static void FillInScsiIOPB();
  302. static void RequestDone();
  303. static void StartNextRequest();
  304. static char *ErrorString();
  305. static Boolean SendJaguarCmd();
  306.  
  307. /*
  308.  *----------------------------------------------------------------------
  309.  *
  310.  * GetJaguarMem --
  311.  *
  312.  *    Make a copy of the Jaguar's memory image in DebugJaguarMem. This
  313.  *    routine is used because the Sprite debugger can't read data
  314.  *    in short VME space. It is only called by the debugger.
  315.  *
  316.  * Results:
  317.  *    The address of the Jaguar memory copied.
  318.  *
  319.  * Side effects:
  320.  *    None.
  321.  *
  322.  *----------------------------------------------------------------------
  323.  */
  324. #ifndef lint
  325. static unsigned int
  326. GetJaguarMem(ctrlNum)
  327.     int    ctrlNum;    /* Controller to number to act upon. */
  328. {
  329.     CopyFromJaguarMem(Controllers[ctrlNum]->memPtr, &DebugJaguarMem, 2048);
  330.     return (unsigned int) Controllers[ctrlNum]->memPtr;
  331. }
  332. #endif
  333.  
  334. /*
  335.  *----------------------------------------------------------------------
  336.  *
  337.  * WaitForResponseBlock --
  338.  *
  339.  *    Wait for a Jaguar command to complete. 
  340.  *
  341.  * Results:
  342.  *    TRUE always. Should probably sent up a timeout handler.
  343.  *
  344.  * Side effects:
  345.  *    None.
  346.  *----------------------------------------------------------------------
  347.  */
  348.  
  349. static void
  350. WaitForResponseBlock(ctrlPtr,crbPtr)
  351.     Controller    *ctrlPtr;         /* Controller to which command 
  352.                    * was submitted. */
  353.     volatile JaguarCRB *crbPtr;   /* Command Response Block to be filled in by
  354.                    * interrupt handler.    */
  355. {
  356.     while (!(crbPtr->status & JAGUAR_CRB_BLOCK_VALID)) {
  357.     Sync_MasterWait(&(ctrlPtr->ctrlCmdWait), &ctrlPtr->mutex,FALSE);
  358.     }
  359.     return;
  360. }
  361.  
  362.  
  363. /*
  364.  *----------------------------------------------------------------------
  365.  *
  366.  * InitializeWorkq --
  367.  *
  368.  *      Send Jaguar the command to initialize the specified work queue
  369.  *    with the given parameters and options. 
  370.  *
  371.  *     NOTE: This routine assumes that the error recovery method used 
  372.  *          in the driver would be to Freeze the Work queue upon error.
  373.  *
  374.  * Results:
  375.  *    TRUE is queue was initialized, FALSE otherwise.
  376.  *
  377.  * Side effects:
  378.  *    A work queue initialize command is send to the controller.
  379.  *
  380.  *----------------------------------------------------------------------
  381.  */
  382. /*ARGSUSED*/
  383. static Boolean
  384. InitializeWorkq(ctrlPtr,workqNum, parity, priority)
  385.     Controller    *ctrlPtr;    /* Controller to initalize Work Queue on. */
  386.     int        workqNum;    /* Workq to initialize must be 1-14. */
  387.     Boolean    parity;        /* TRUE - parity check should be enabled. When
  388.                  * communicated thru this workq. FALSE if not. 
  389.                  */
  390.     int        priority;    /* The priority level of this workq. (1-14) */
  391. {
  392.     JaguarIOPB        inMemIOPB;
  393.     volatile register JaguarIOPB    *iopb = &inMemIOPB;
  394.     JaguarCRB        crb;
  395.     Boolean        good;
  396.  
  397.     if (devJaguarDebug > 3) {
  398.     printf("%s: Initializing workQueue %d ...\n", ctrlPtr->name, workqNum);
  399.     }
  400.  
  401.     /*
  402.      * Build the appropriate Initialized Work Queue Command IOPB
  403.      * and send it to workQ 0. We must use workq 0 for this comand.
  404.      */
  405.     bzero((char *) &crb, sizeof(crb));
  406.     bzero((char *) iopb, sizeof(*iopb));
  407.     iopb->command = JAGUAR_INIT_WORK_QUEUE_CMD;
  408.     iopb->options = JAGUAR_IOPB_INTR_ENA;
  409.     iopb->intrVector = ctrlPtr->intrVector;
  410.     iopb->intrLevel = ctrlPtr->intrLevel;
  411.     iopb->cmd.workQueueArg.number = workqNum;
  412.     iopb->cmd.workQueueArg.options =
  413.              JAGUAR_WQ_INIT_QUEUE | 
  414.              JAGUAR_WQ_FREEZE_QUEUE | 
  415. #ifdef youWantItNotToWork
  416.     /*
  417.      * Setting the JAGUAR_WQ_PARITY_ENABLE bit in the workQueue options
  418.      * causes the HBA to quit working.
  419.      */
  420.              (parity ? JAGUAR_WQ_PARITY_ENABLE : 0);
  421. #else
  422.             0;
  423. #endif
  424.  
  425.     iopb->cmd.workQueueArg.slots = NUM_CQE;
  426.     iopb->cmd.workQueueArg.priority = priority;
  427.     /*
  428.      * Send the command into work queue zero. SendJaguarCmd will do the
  429.      * waiting for us and return 
  430.      */
  431.     MASTER_LOCK(&ctrlPtr->mutex);
  432.     good = SendJaguarCmd(ctrlPtr, 0, iopb, FILL_IN_CRB_ACTION,(ClientData)&crb);
  433.     MASTER_UNLOCK(&ctrlPtr->mutex);
  434.     if (!good) {
  435.     panic("%s: Initialize WorkQ %d did not finished.\n",ctrlPtr->name,
  436.            workqNum);
  437.     return (FALSE);
  438.     }
  439.     if (crb.status & (JAGUAR_CRB_ERROR|JAGUAR_CRB_EXCEPTION)) {
  440.     printf("%s: Initialize WorkQ %d failed with error 0x%s %s\n",
  441.          ctrlPtr->name, workqNum, crb.iopb.returnStatus, 
  442.          ErrorString(crb.iopb.returnStatus));
  443.     return (FALSE);
  444.  
  445.     }
  446.     if (devJaguarDebug > 3) {
  447.     printf("%s: WorkQueue %d initialized\n", ctrlPtr->name, workqNum);
  448.     }
  449.     return (TRUE);
  450. }
  451.  
  452. /*
  453.  *----------------------------------------------------------------------
  454.  *
  455.  * PerformDiagnostics --
  456.  *
  457.  *    Perform an extensive diagnostics test of the JaguarHBA.
  458.  *
  459.  *
  460.  * Results:
  461.  *    TRUE if the controller passes the test. FALSE if controller is broken.
  462.  *
  463.  * Side effects:
  464.  *    The docuementation says the JAGUAR_DIAG_CMD can take several
  465.  *    minutes to execute. I let it run for 45 mins and it still didn't
  466.  *    finish.  
  467.  *
  468.  *----------------------------------------------------------------------
  469.  */
  470.  
  471. static Boolean
  472. PerformDiagnostics(memPtr, name)
  473.     volatile JaguarMem *memPtr;    /* Pointer to VME Short IO space of HBA. */
  474.     char    *name;        /* Name of the controller for error messges. */
  475. {
  476.      register volatile JaguarCQE  *cqe;
  477.      register volatile JaguarIOPB *iopb;
  478.      register volatile JaguarCRB  *crb;
  479.      Boolean good = TRUE;
  480.  
  481.     cqe  = &(memPtr->mce);
  482.     iopb = &(memPtr->masterIOPB);
  483.     crb = &(memPtr->crb);
  484.     /*
  485.      * The command we send is the Perform Diagnostics command.
  486.      */
  487.     ZeroJaguarMem((short *)iopb, sizeof(iopb));
  488.     iopb->command = JAGUAR_DIAG_CMD;
  489.     {
  490.     register unsigned int status;
  491.     /*
  492.      * Send the command off and wait for response.
  493.      */
  494.     cqe->controlReg = JAGUAR_CQE_GO_BUSY;
  495.     if (!WaitForBitSet(&(crb->status),JAGUAR_CRB_BLOCK_VALID,100000)) {
  496.          panic("%s diag timeout. status = 0x%x\n", name, 
  497.            crb->status);
  498.          return FALSE;
  499.     }
  500.     /*
  501.      * Check for happy completion status.
  502.      */
  503.     status = crb->status;
  504.     if (!(status & JAGUAR_CRB_COMMAND_COMPLETE)) {
  505.          panic("%s diag cmd didn't complete, status 0x%x\n",
  506.             name, status);
  507.          return FALSE;
  508.     }
  509.     if (status & (JAGUAR_CRB_ERROR|JAGUAR_CRB_EXCEPTION)) {
  510.          printf("%s diag cmd error 0x%x, status 0x%x\n",
  511.             name, crb->iopb.returnStatus, status);
  512.         good = FALSE;
  513.     }
  514.     if (crb->iopb.cmd.diagArg.romTest != 0xffff) {
  515.         printf("%s failed ROM test, result = 0x%x\n", name ,
  516.                 crb->iopb.cmd.diagArg.romTest);
  517.         good = FALSE;
  518.     }
  519.     if (crb->iopb.cmd.diagArg.scrRamTest != 0xffff) {
  520.         printf("%s failed Scratch pad RAM test, result = 0x%x\n", name ,
  521.                 crb->iopb.cmd.diagArg.scrRamTest);
  522.         good = FALSE;
  523.     }
  524.     if (crb->iopb.cmd.diagArg.bufRamTest != 0xffff) {
  525.         printf("%s failed Buffer RAM test, result = 0x%x\n", name ,
  526.                 crb->iopb.cmd.diagArg.bufRamTest);
  527.         good = FALSE;
  528.     }
  529.     if (crb->iopb.cmd.diagArg.eventRamTest != 0xffff) {
  530.         printf("%s failed Evant RAM test, result = 0x%x\n", name ,
  531.                 crb->iopb.cmd.diagArg.eventRamTest);
  532.         good = FALSE;
  533.     }
  534.     if (crb->iopb.cmd.diagArg.priPort != 0xffff) {
  535.         printf("%s failed Primary SCSI port test, result = 0x%x\n", name ,
  536.                 crb->iopb.cmd.diagArg.priPort);
  537.         good = FALSE;
  538.     }
  539.     if (crb->iopb.cmd.diagArg.secPort != 0xffff) {
  540.         printf("%s failed Secondary SCSI port test, result = 0x%x\n", name ,
  541.                 crb->iopb.cmd.diagArg.secPort);
  542.         good = FALSE;
  543.     }
  544.     /*
  545.      * If we got here the controller init cmd successfully completed.
  546.      * Acknowledge the command to release the CRB.
  547.      */
  548.     crb->status = 0;
  549.     }
  550.     return good;
  551. }
  552.  
  553.  
  554. /*
  555.  *----------------------------------------------------------------------
  556.  *
  557.  * InitializeJaguar --
  558.  *
  559.  *    Initialize the Jaguar HBA and ready it for commands.
  560.  *
  561.  *    This routine assumes that the controller is MASTER_LOCKed()
  562.  *
  563.  * Results:
  564.  *    TRUE if the controller initializes. FALSE if controller is broken.
  565.  *
  566.  * Side effects:
  567.  *    Controller is reset and initialized. This causes the SCSI bus(es) to
  568.  *    be reset and any in progress commands aborted. 
  569.  *
  570.  *----------------------------------------------------------------------
  571.  */
  572.  
  573. static Boolean
  574. InitializeJaguar(memPtr, name, intrLevel, intrVector)
  575.     volatile JaguarMem *memPtr;    /* Pointer to VME Short IO space of HBA. */
  576.     char    *name;        /* Name of the controller for error messges. */
  577.     int        intrLevel;    /* VME Interrupt level for HBA. */
  578.     int        intrVector;    /* VME Interrupt vector for HBA. */
  579. {
  580.      register volatile JaguarMCSB *mcsb = &(memPtr->mcsb);
  581.      register volatile JaguarCQE  *cqe;
  582.      register volatile JaguarIOPB *iopb;
  583.      register volatile JaguarCRB  *crb;
  584.  
  585.     /*
  586.      * Start off with a clean slate by reseting the board. Documentation
  587.      * says must keep reset bit set at least 50 microseconds.
  588.      * We give it 1 millesecond of reset .
  589.      */
  590.  
  591.     mcsb->control = JAGUAR_MCR_RESET;
  592.     MACH_DELAY(1000); 
  593.     mcsb->control = 0;
  594.     /*
  595.      * Wait for the Jaugar to signal Board OK. Board OK not valid for
  596.      * 100 microseconds after reset. We give it 1 millisecond to be happy.
  597.      *
  598.      * One millisecond does not appear to be long enough because the
  599.      * OK bit is still not set. We increase the amount to 1 second to 
  600.      * make sure.
  601.      */
  602.     MACH_DELAY(1000*1000);
  603.     if (!(mcsb->status & JAGUAR_MSR_BOARD_OK)) {
  604.     panic("Warning: %s board not OK, status = 0x%x\n", name, mcsb->status);
  605.     return (FALSE);
  606.     }
  607.  
  608.  
  609.     /*
  610.      * Initialize the rest of the MCSB. Currently we wont deal with 
  611.      * queue available interrupts so we turn them off.
  612.      */
  613.     mcsb->queueAvail = 0;
  614.     mcsb->queueHead = 0;
  615.     mcsb->reserved[0] = mcsb->reserved[1] = mcsb->reserved[2] = 0;
  616.     /*
  617.      * Initialize the Command Queue (CQ). To do this we clear out the 
  618.      * CQE's and point them at their IOPBs. Clear out the IOPBs too.
  619.      */
  620.      {
  621.      int    i;
  622.      cqe  = memPtr->cmdQueue;
  623.      iopb = memPtr->iopbs;
  624.      for (i = 0; i < NUM_CQE; i++, cqe++, iopb++) {
  625.          cqe->controlReg = 0;
  626.          cqe->iopbOffset = POINTER_TO_OFFSET(iopb,memPtr);
  627.          cqe->iopbLength = sizeof(JaguarIOPB)/4;
  628.          cqe->commandTag[0] = 0;
  629.          cqe->commandTag[1] = 0;
  630.          cqe->workQueue = 0;
  631.          cqe->reserved = 0;
  632.      }
  633.      ZeroJaguarMem((short *) iopb, sizeof(JaguarIOPB) * NUM_CQE);
  634.    }
  635.     /*
  636.      * Clear the area to be used as the Command Response Block.
  637.      */
  638.     crb = &(memPtr->crb);
  639.     ZeroJaguarMem((short *) crb, sizeof(JaguarCRB));
  640.  
  641.     /*
  642.      * Initialize the Master Control Enter (MCE) so we can send commands
  643.      * to the board. 
  644.      */
  645.     cqe  = &(memPtr->mce);
  646.     iopb = &(memPtr->masterIOPB);
  647.     cqe->controlReg = 0;
  648.     cqe->iopbOffset = POINTER_TO_OFFSET(iopb,memPtr);
  649.     cqe->iopbLength = sizeof(JaguarIOPB)/4;
  650.     cqe->workQueue = 0;
  651.     cqe->reserved = 0;
  652.     cqe->commandTag[0] = 0;
  653.     cqe->commandTag[1] = 0;
  654.     ZeroJaguarMem((short *)iopb , sizeof(JaguarIOPB));
  655.  
  656.     if (devJaguarDebug > 9) {
  657.     if (!PerformDiagnostics(memPtr, name)) {
  658.         printf("Warning: %s failed diagnostics\n");
  659.     }
  660.     }
  661.     /*
  662.      * The first command we send is the Initialize controller command.
  663.      * In order to send this command we must build a Controller
  664.      * Initialization Block (CIP) in JaguarMem.  Since this block is 
  665.      * not needed after initialization, we overlay the scatter sgElements
  666.      * gather vectors with the CIP.
  667.      */
  668.     {
  669.     volatile JaguarCIB *cib = (volatile JaguarCIB *) (memPtr->sgElements);
  670.     ZeroJaguarMem((short *) cib, sizeof(JaguarCIB));
  671.  
  672.     cib->numQueueSlots = NUM_CQE;
  673.     cib->dmaBurstCount = DMA_BURST_COUNT;
  674.     cib->normalIntrVector =    JAGUAR_INTR_VECTOR(intrLevel,intrVector);
  675.     cib->errorIntrVector = JAGUAR_INTR_VECTOR(intrLevel,intrVector);
  676.     cib->priTargetID = JAGUAR_DEFAULT_BUS_ID;
  677.     cib->secTargetID = JAGUAR_DEFAULT_BUS_ID;
  678.     cib->offsetCRB = POINTER_TO_OFFSET(&(memPtr->crb),memPtr);
  679.     SET_LONG(cib->scsiSelTimeout, SELECTION_TIMEOUT);
  680.     SET_LONG(cib->scsiReselTimeout, RESELECTION_TIMEOUT);
  681.     SET_LONG(cib->vmeTimeout, VME_TIMEOUT);
  682.  
  683.     ZeroJaguarMem((short *)iopb, sizeof(iopb));
  684.     iopb->command = JAGUAR_INIT_HBA_CMD;
  685.     iopb->addrModifier = JAGUAR_BOARD_MEM_TYPE;
  686.     SET_LONG(iopb->bufferAddr,POINTER_TO_OFFSET(cib,memPtr));
  687.     }
  688.     {
  689.     register unsigned int status;
  690.     /*
  691.      * Send the command off and wait for response.
  692.      */
  693.     cqe->controlReg = JAGUAR_CQE_GO_BUSY;
  694.     if (!WaitForBitSet(&(crb->status),JAGUAR_CRB_BLOCK_VALID,10000)) {
  695.          panic("%s init controller timeout. status = 0x%x\n", name, 
  696.            crb->status);
  697.          return FALSE;
  698.     }
  699.     /*
  700.      * Check for happy completion status.
  701.      */
  702.     status = crb->status;
  703.     if (!(status & JAGUAR_CRB_COMMAND_COMPLETE)) {
  704.          panic("%s init ctrl cmd didn't complete, status 0x%x\n",
  705.             name, status);
  706.          return FALSE;
  707.     }
  708.     if (status & (JAGUAR_CRB_ERROR|JAGUAR_CRB_EXCEPTION)) {
  709.          panic("%s init ctrl cmd error 0x%x, status 0x%x\n",
  710.             name, iopb->returnStatus, status);
  711.          return FALSE;
  712.     }
  713.     /*
  714.      * If we got here the controller init cmd successfully completed.
  715.      * Acknowledge the command to release the CRB.
  716.      */
  717.     crb->status = 0;
  718.     /*
  719.      * Start Queue Mode operation and wait for ack.
  720.      */
  721.     mcsb->control |= JAGUAR_MCR_START_QUEUES;
  722.     if (!WaitForBitSet(&(crb->status),JAGUAR_CRB_BLOCK_VALID,10000)) {
  723.          panic("%s start queue mode timeout.\n",name);
  724.          return FALSE;
  725.     }
  726.     status = crb->status;
  727.     if (!(status & JAGUAR_CRB_QUEUE_START)) {
  728.          panic("%s start queue mode bad status 0x%x.\n",name,status);
  729.          return FALSE;
  730.     }
  731.     crb->status = 0;
  732.     }
  733.     /*
  734.      * Be neat! Clear out the rest of the Jaguar memory.
  735.      */
  736.     ZeroJaguarMem((short *) (memPtr->sgElements), 
  737.              NUM_SG_ELEMENTS * sizeof(JaguarSG));
  738.     ZeroJaguarMem((short *) (memPtr->padding), MEM_PAD);
  739.     /*
  740.      * Notifiy the world that we are alive by printing our Controller
  741.      * Configuration Status Block. This will be useful if someone ask
  742.      * the question: "What rev PROMs are you running?"
  743.      */
  744.     { 
  745.     JaguarCCSB css;
  746.     /*
  747.      * Note we copy the CCSB from the board because passing pointers
  748.      * into Jaguar  Memory to printf would be a no-no because we 
  749.      * don't have control of the type memory references done by
  750.      * printf.
  751.      */
  752.     CopyFromJaguarMem((short *)&(memPtr->css),(short *)&css, sizeof(css));
  753.     printf("%s firmware (%3s-%c-%3s) %c%c/%c%c/%c%c ",
  754.         name, css.code, css.variation, css.firmwareLevel,
  755.         css.firmwareDate[0], css.firmwareDate[1],
  756.         css.firmwareDate[2], css.firmwareDate[3], 
  757.         css.firmwareDate[6], css.firmwareDate[7]);
  758.     printf("%dK RAM bus0ID %d bus1ID %d\n", css.bufferRAMsize,
  759.         css.primaryID, css.secondaryID);
  760.     }
  761.     return TRUE;
  762. }
  763.  
  764. static struct errorString {
  765.     int    code;
  766.     char *string ;
  767. } errorStrings[] = JAGUAR_ERROR_CODES;
  768. #define NUM_ERROR_STRINGS (sizeof(errorStrings) / sizeof(errorStrings[0]))
  769.  
  770.  
  771. /*
  772.  *----------------------------------------------------------------------
  773.  *
  774.  * ErrorString --
  775.  *
  776.  *    Return a string describing a Jaguar error code.
  777.  *
  778.  * Results:
  779.  *    An error string.
  780.  *
  781.  * Side effects:
  782.  *    None.
  783.  *
  784.  *----------------------------------------------------------------------
  785.  */
  786.  
  787. static char *
  788. ErrorString(returnStatus)
  789.     unsigned short    returnStatus;
  790. {
  791.     int    code = returnStatus & 0xff;
  792.     int    i;
  793.  
  794.     for (i = 0; i < NUM_ERROR_STRINGS; i++) {
  795.     if (errorStrings[i].code == code) {
  796.         return errorStrings[i].string;
  797.     }
  798.     }
  799.     return "Unknown error";
  800. }
  801.  
  802. /*
  803.  *----------------------------------------------------------------------
  804.  *
  805.  * MapJaguarToSpriteErrorCode --
  806.  *
  807.  *    Map a jaguar return error code to a Sprite ReturnStatus value.
  808.  *
  809.  * Results:
  810.  *    A sprite return status value.
  811.  *
  812.  * Side effects:
  813.  *    None.
  814.  *
  815.  *----------------------------------------------------------------------
  816.  */
  817.  
  818. static ReturnStatus 
  819. MapJaguarToSpriteErrorCode(status)
  820.     unsigned short    status;
  821. {
  822.     int    code = status & 0xff;
  823.  
  824.     if (code == 0) {
  825.     return SUCCESS;
  826.     }
  827.     /*
  828.      * Error codes between 0x20 and 0x30 are VME bus type errors.
  829.      */
  830.     if (code >= 0x20 && code < 0x30) {
  831.     return DEV_DMA_FAULT;
  832.     }
  833.     return DEV_HARD_ERROR;
  834. }
  835.  
  836. /*
  837.  *----------------------------------------------------------------------
  838.  *
  839.  *  SendScsiCommand --
  840.  *
  841.  *    Enqueue a SCSI command into the Jaguar command queue.
  842.  *
  843.  * Results:
  844.  *    
  845.  *
  846.  * Side effects:
  847.  *
  848.  *----------------------------------------------------------------------
  849.  */
  850.  
  851. static Boolean
  852. SendScsiCommand( devPtr, scsiCmdPtr)
  853.     Device *devPtr; /* Jaguar device for command. */
  854.     ScsiCmd    *scsiCmdPtr; /* SCSI command to send. */
  855.  
  856. {
  857.     volatile JaguarIOPB iopbMem;    
  858.     Boolean    retVal;
  859.  
  860.     /*
  861.      * Check to see if we can use normal PASS_THRU command or must be
  862.      * PASS_THRU_EXT extented.
  863.      */
  864.     if (scsiCmdPtr->commandBlockLen <= sizeof(iopbMem.cmd.scsiArg.cmd)) {
  865.     /*
  866.      * We can use a simple PASS_THRU command. 
  867.      */
  868.     FillInScsiIOPB(devPtr, scsiCmdPtr, &iopbMem);
  869.     retVal = SendJaguarCmd(devPtr->ctrlPtr, devPtr->workQueue, &iopbMem, 
  870.                 SCSI_CMD_ACTION, (ClientData) scsiCmdPtr);
  871.     } else {
  872.     /*
  873.      * Can't handle PASS_THRU_EXT command yet.
  874.      */
  875.     panic("%s: SCSI command too large, %d bytes.\n",devPtr->ctrlPtr->name, 
  876.                     scsiCmdPtr->commandBlockLen);
  877.     return (FALSE);
  878.     }
  879.     return (retVal);
  880.  
  881. }
  882.  
  883. /*
  884.  *----------------------------------------------------------------------
  885.  *
  886.  * DevJaguarIntr --
  887.  *
  888.  *    Process a Jaguar interrupt by processing the entry in the ctrl's
  889.  *    Command Response Block and reseting the controller.
  890.  *
  891.  * Results:
  892.  *    TRUE if an interrupt was process. FALSE if not interrupt was
  893.  *    present on this controller.
  894.  *
  895.  * Side effects:
  896.  *    None.
  897.  *
  898.  *----------------------------------------------------------------------
  899.  */
  900.  
  901. Boolean
  902. DevJaguarIntr(clientData)
  903.     ClientData    clientData;    /* Controller to process. */
  904. {
  905.     register volatile JaguarCRB *crb;
  906.     unsigned int            status;
  907.     unsigned int             returnStatus;
  908.     CmdAction                *actionPtr;
  909.     register Controller         *ctrlPtr;
  910.  
  911.     ctrlPtr = (Controller *) clientData;
  912.     crb = &(ctrlPtr->memPtr->crb);
  913.     /*
  914.      * Check the controller's CRB. If BLOCK_VALID is we have some sort
  915.      * of condition present.
  916.      */
  917.     status = crb->status;
  918.     if (!(status & JAGUAR_CRB_BLOCK_VALID)) {
  919.     return (FALSE);
  920.     }
  921.     /*
  922.      * Classify the condition. If should be one of the following:
  923.      * 1) A command just completed - COMMAND_COMPLETE.
  924.      * 2) Queue mode was started - QUEUE_START
  925.      * 3) A command queue entry became available. - QUEUE_AVAILABLE
  926.      * 
  927.      * QUEUE_START interrupts are uninteresting to us. No processing
  928.      * is necessary.  QUEUE_AVAILABLE are also uninteresting and 
  929.      * unless I don't understand something impossible because we
  930.      * never set anything in the IQAR on the MCSB. Because these
  931.      * interrupt are boring we processing them first.
  932.      */
  933.     if (status & (JAGUAR_CRB_QUEUE_START|JAGUAR_CRB_QUEUE_AVAILABLE)){
  934.     /*
  935.      * Clear the interrupt.
  936.      */
  937.     crb->status = 0;
  938.     return (TRUE);
  939.     }
  940.     if (!(status & JAGUAR_CRB_COMMAND_COMPLETE)) {
  941.     printf("Warning: %s unknown interrupt, status = 0x%x\n", 
  942.         ctrlPtr->name, status);
  943.     crb->status = 0;
  944.     return (TRUE);
  945.     }
  946.     /*
  947.      * Since all work queues should be setup with FREEZE on error and not
  948.      * ABORT on error, take aborted commands very seriously.
  949.      */
  950.     if (status & JAGUAR_CRB_ABORTED) {
  951.     panic("%s command aborted, status = 0x%x!!!\n", 
  952.             ctrlPtr->name,status);
  953.     crb->status = 0;
  954.     return (TRUE);
  955.     }
  956.     /*
  957.      * We have a real COMMAND_COMPLETION. Read the tag out of the
  958.      * return CQE to find the action to be performed. Also, read the
  959.      * return status from the IOPB returned.
  960.      */
  961.     actionPtr = &(ctrlPtr->cmdAction[crb->commandTag[0]]);
  962.     /*
  963.      * Release the device's DMA space.
  964.      */
  965.     if (!VmMachIsXbusMem(actionPtr->dmaBuffer) && actionPtr->dmaBufferLen > 0) {
  966.     if (((unsigned)actionPtr->dmaBuffer) & 0x80000000) {
  967.         VmMach_32BitDMAFree(actionPtr->dmaBufferLen,
  968.             actionPtr->dmaBuffer);
  969.     } else {
  970.         VmMach_DMAFree(actionPtr->dmaBufferLen, actionPtr->dmaBuffer);
  971.     }
  972.     }
  973.     returnStatus = crb->iopb.returnStatus;
  974.     /*
  975.      * Check to see an error.
  976.      */
  977.     if (actionPtr->action & FILL_IN_CRB_ACTION) {
  978.     CopyFromJaguarMem((short *)crb,(short *) actionPtr->actionArg, 
  979.                 sizeof(*crb));
  980.     } 
  981.     if (actionPtr->action & SCSI_CMD_ACTION) {
  982.     ScsiCmd    *scsiCmdPtr = (ScsiCmd *) actionPtr->actionArg;
  983.     Device    *devPtr = (Device *) (ctrlPtr->devices[crb->workQueue-1]);
  984.     ReturnStatus    spriteStatus = SUCCESS;
  985.     int    transferCount = READ_LONG(crb->iopb.maxXferLen);
  986.     if (returnStatus & 0xff) {
  987.         /*
  988.          * Error code 0x34 means that the transfer count didn't match
  989.          * the number of bytes transfers. We don't consider this an 
  990.          * error.
  991.          */
  992.         if ((returnStatus & 0xff) != 0x34)  {
  993.         spriteStatus = MapJaguarToSpriteErrorCode(returnStatus);
  994.         transferCount = 0;
  995.         } 
  996.         if (spriteStatus != SUCCESS) {
  997.         printf("Warning: Device %s HBA error 0x%x: %s\n",
  998.             devPtr->handle.locationName, returnStatus,
  999.             ErrorString(returnStatus));
  1000.         }
  1001.     }  
  1002.     devPtr->numActiveCmds--;
  1003.     RequestDone(devPtr, scsiCmdPtr, spriteStatus,
  1004.             (returnStatus >> 8) & 0xff, transferCount);
  1005.     StartNextRequest(devPtr);
  1006.  
  1007.     }
  1008.     if (IS_WAIT_ACTION(actionPtr->action)) {
  1009.     Sync_MasterBroadcast(&(ctrlPtr->ctrlCmdWait));
  1010.     }
  1011.     actionPtr->action = UNUSED_ACTION;
  1012.     crb->status = 0;
  1013.     return (TRUE);
  1014.  
  1015. }
  1016.  
  1017.  
  1018. /*
  1019.  *----------------------------------------------------------------------
  1020.  *
  1021.  *  SendJaguarCmd --
  1022.  *
  1023.  *    Enter a Jaguar command into the specified Jaguar work Queue.
  1024.  *
  1025.  * Results:
  1026.  *    TRUE if the command was started. FALSE otherwise.
  1027.  *
  1028.  * Side effects:
  1029.  *    Those of Jaguar commands.
  1030.  *
  1031.  *----------------------------------------------------------------------
  1032.  */
  1033.  
  1034. static Boolean
  1035. SendJaguarCmd(ctrlPtr, workQueue, iopbPtr, action, actionArg)
  1036.     Controller    *ctrlPtr;    /* Controller to enter command. */
  1037.     int        workQueue;    /* Command destination workq number. */
  1038.     volatile JaguarIOPB *iopbPtr;    /* Jaguar IOPB command block. */
  1039.     int        action;        /* Action to be performed on completion. */
  1040.     ClientData  actionArg;    /* Argument to action. */
  1041. {
  1042.     volatile JaguarMem    *memPtr = ctrlPtr->memPtr;
  1043.     volatile JaguarCQE    *cqe;
  1044.     volatile JaguarIOPB    *iopb;
  1045.     Boolean    noDMA = FALSE;
  1046.     unsigned int  addr;
  1047.  
  1048.     /*
  1049.      * Work queue is special because it has only one entry. To keep from
  1050.      * overrunning it we must observe a locking protocol.
  1051.      */ 
  1052.     if (workQueue == 0) {
  1053.     LockWorkq0(ctrlPtr);    
  1054.     }
  1055.     /*
  1056.      * Get the next Command Queue entry stepping the next available queue
  1057.      * entry pointer around the circular queue.
  1058.      */
  1059.     cqe = ctrlPtr->nextCQE++;
  1060.     if ((ctrlPtr->nextCQE - memPtr->cmdQueue) >= NUM_CQE) {
  1061.     ctrlPtr->nextCQE = memPtr->cmdQueue;
  1062.     }
  1063.     if (cqe->controlReg & JAGUAR_CQE_GO_BUSY) {
  1064.     panic("%s: Command Queue Full\n", ctrlPtr->name);
  1065.     }
  1066.     addr = (unsigned) READ_LONG(iopbPtr->bufferAddr);
  1067.     {
  1068.     /*
  1069.      * If the address has the lowest hit set then it was already
  1070.      * pointing into the DMA space so we set the dmaBufferLen
  1071.      * to zero to cause the interrupt handle not to free it.
  1072.      */
  1073.     if (addr & 1) { 
  1074.         addr = addr & ~1;
  1075.         SET_LONG(iopbPtr->bufferAddr,addr);
  1076.         noDMA = TRUE;
  1077.     }
  1078.     }
  1079.     /*
  1080.      * Find to IOPB we hardwired this CQE to point at.   
  1081.      */
  1082.     iopb = memPtr->iopbs + (cqe - memPtr->cmdQueue);
  1083.     /*
  1084.      * Fill in the on-board iopb with the one our caller passed us.
  1085.      */
  1086.     CopyToJaguarMem((short *) iopbPtr, (short *)iopb, sizeof(*iopb));
  1087.     cqe->workQueue = workQueue;
  1088.      /*
  1089.      * Inform interrupt handler of the action we want on completion.
  1090.      * To do this we must allocate a cmdAction buffer. We store the 
  1091.      * index into cmdAction in the cqe's commandTag to allow the 
  1092.      * interrupt handler to associated it with the command.
  1093.      */
  1094.     {
  1095.     CmdAction *actionPtr;
  1096.     while (ctrlPtr->cmdAction[ctrlPtr->nextActionBuffer].action
  1097.                     != UNUSED_ACTION) {
  1098.         ctrlPtr->nextActionBuffer++;
  1099.         if (ctrlPtr->nextActionBuffer >= NUM_ACTIONS) {
  1100.         ctrlPtr->nextActionBuffer = 0;
  1101.         }
  1102.     }
  1103.     actionPtr = &(ctrlPtr->cmdAction[ctrlPtr->nextActionBuffer]);
  1104.     actionPtr->action = action;
  1105.     /*
  1106.      * If the address has the lowest hit set then it was already
  1107.      * pointing into the DMA space so we set the dmaBufferLen
  1108.      * to zero to cause the interrupt handle not to free it.
  1109.      */
  1110.     if (noDMA) { 
  1111.         actionPtr->dmaBufferLen = 0;
  1112.     } else { 
  1113.         actionPtr->dmaBufferLen = READ_LONG(iopbPtr->maxXferLen);
  1114.     }
  1115.     if ((unsigned)addr & 0x80000000) {
  1116.         actionPtr->dmaBuffer = (Address) (addr);
  1117.     } else {
  1118.         actionPtr->dmaBuffer = (Address) (addr + VMMACH_DMA_START_ADDR);
  1119.     }
  1120.     actionPtr->actionArg = actionArg;
  1121.         cqe->commandTag[0] = ctrlPtr->nextActionBuffer;
  1122.     }
  1123.     /*
  1124.      * Inform the controller that the command is ready.
  1125.      */
  1126.     cqe->controlReg = JAGUAR_CQE_GO_BUSY;
  1127.     /*
  1128.      * If the caller specified a CRB we wait for the response.
  1129.      */
  1130.     if(IS_WAIT_ACTION(action)) { 
  1131.     WaitForResponseBlock(ctrlPtr,(volatile JaguarCRB *) actionArg);
  1132.     }
  1133.     if (workQueue == 0) {
  1134.     UnLockWorkq0(ctrlPtr);    
  1135.     }
  1136.     return (TRUE);
  1137. }
  1138.  
  1139. /*
  1140.  *----------------------------------------------------------------------
  1141.  *
  1142.  * LockWorkq0 --
  1143.  *
  1144.  *    Grap exclusive access to work queue 0 of the specified controller.
  1145.  *
  1146.  * Results:
  1147.  *    None.
  1148.  *
  1149.  * Side effects:
  1150.  *    None.
  1151.  *
  1152.  *----------------------------------------------------------------------
  1153.  */
  1154.  
  1155. static void
  1156. LockWorkq0(ctrlPtr)
  1157.     Controller    *ctrlPtr;
  1158. {
  1159.     while (ctrlPtr->workQueue0Busy) {
  1160.     Sync_MasterWait(&(ctrlPtr->ctrlQueue0Wait), &ctrlPtr->mutex,FALSE);
  1161.     }
  1162.     ctrlPtr->workQueue0Busy = TRUE;
  1163. }
  1164.  
  1165. /*
  1166.  *----------------------------------------------------------------------
  1167.  *
  1168.  * UnLockWorkq0 --
  1169.  *
  1170.  *    Release exclusive access to work queue 0 of the specified controller.
  1171.  *
  1172.  * Results:
  1173.  *    None.
  1174.  *
  1175.  * Side effects:
  1176.  *    None.
  1177.  *
  1178.  *----------------------------------------------------------------------
  1179.  */
  1180.  
  1181. static void
  1182. UnLockWorkq0(ctrlPtr)
  1183.     Controller    *ctrlPtr;
  1184. {
  1185.     ctrlPtr->workQueue0Busy = FALSE;
  1186.     Sync_MasterBroadcast(&(ctrlPtr->ctrlQueue0Wait));
  1187. }
  1188.  
  1189.  
  1190. /*
  1191.  *----------------------------------------------------------------------
  1192.  *
  1193.  * CopyFromJaguarMem --
  1194.  *
  1195.  *    Copy a block from Jaguar Memory to host memory.
  1196.  *     NOTE:
  1197.  *        This routine assumes that both the block and the host
  1198.  *        memory region are aligned on a 2 byte boundry and are
  1199.  *        an even number of bytes long.
  1200.  *
  1201.  * Results:
  1202.  *    None.
  1203.  *
  1204.  * Side effects:
  1205.  *    None.
  1206.  *
  1207.  *----------------------------------------------------------------------
  1208.  */
  1209.  
  1210. static void
  1211. CopyFromJaguarMem(blockPtr, hostPtr, blockSize)
  1212.     register short    *blockPtr;    /* Block in Jaguar Memory to copy. */
  1213.     register short    *hostPtr;    /* Address in host memory. */
  1214.     register int    blockSize;    /* Size of block in bytes. */
  1215.  
  1216. {
  1217.     /*
  1218.      * We do the copy 2 bytes at a time because the Jaguar is in 16 bit
  1219.      * data IO space of the VME bus.
  1220.      */
  1221.     while (blockSize > 0) {
  1222.     *(hostPtr++) = *(blockPtr++);
  1223.     blockSize -= sizeof(short);
  1224.     }
  1225. }
  1226.  
  1227.  
  1228. /*
  1229.  *----------------------------------------------------------------------
  1230.  *
  1231.  * CopyToJaguarMem --
  1232.  *
  1233.  *    Copy a block to Jaguar Memory from host memory.
  1234.  *     NOTE:
  1235.  *        This routine assumes that both the block and the host
  1236.  *        memory region are aligned on a 2 byte boundry and are
  1237.  *        an even number of bytes long.
  1238.  *
  1239.  * Results:
  1240.  *    None.
  1241.  *
  1242.  * Side effects:
  1243.  *    None.
  1244.  *
  1245.  *----------------------------------------------------------------------
  1246.  */
  1247.  
  1248. static void
  1249. CopyToJaguarMem(blockPtr, hostPtr, blockSize)
  1250.     register short    *blockPtr;    /* Block in Jaguar Memory to copy. */
  1251.     register short    *hostPtr;    /* Address in host memory. */
  1252.     register int    blockSize;    /* Size of block in bytes. */
  1253.  
  1254. {
  1255.     /*
  1256.      * We do the copy 2 bytes at a time because the Jaguar is in 16 bit
  1257.      * data IO space of the VME bus.
  1258.      */
  1259.     while (blockSize > 0) {
  1260.     *(hostPtr++) = *(blockPtr++);
  1261.     blockSize -= sizeof(short);
  1262.     }
  1263. }
  1264.  
  1265.  
  1266. /*
  1267.  *----------------------------------------------------------------------
  1268.  *
  1269.  * ZeroJaguarMem --
  1270.  *
  1271.  *    Zero a block of Jaguar board memory. 
  1272.  *
  1273.  * NOTE: This routine assumes the block is aligned on a 2 byte boundry and
  1274.  *     is an even number of bytes long.
  1275.  *
  1276.  * Results:
  1277.  *    None.
  1278.  *
  1279.  * Side effects:
  1280.  *    None.
  1281.  *
  1282.  *----------------------------------------------------------------------
  1283.  */
  1284.  
  1285. static void
  1286. ZeroJaguarMem(blockPtr, blockSize)
  1287.     register short    *blockPtr;    /* Pointer to block to zero. */
  1288.     register int    blockSize;    /* Number of bytes in the block. */
  1289. {
  1290.     /*
  1291.      * We do the zeroing 2 bytes at a time because the Jaguar is in 16 bit
  1292.      * data IO space of the VME bus.
  1293.      */
  1294.     while (blockSize > 0) {
  1295.     *(blockPtr++) = 0;
  1296.     blockSize -= sizeof(short);
  1297.     }
  1298. }
  1299.  
  1300.  
  1301. /*
  1302.  *----------------------------------------------------------------------
  1303.  *
  1304.  *  WaitForBitSet --
  1305.  *
  1306.  *    Wait for a bit to become set in a Jaguar word.
  1307.  *
  1308.  *
  1309.  * Results:
  1310.  *    TRUE if the bit appears. FALSE if we timeout.
  1311.  *
  1312.  * Side effects:
  1313.  *    None.
  1314.  *
  1315.  *----------------------------------------------------------------------
  1316.  */
  1317.  
  1318. static Boolean
  1319. WaitForBitSet(wordPtr, bit, maxCount)
  1320.     register volatile unsigned short *wordPtr;    /* Word to check. */
  1321.     register unsigned short bit;    /* Bit to check for. */
  1322.     int         maxCount;            /* Number of 100 microseconds to check 
  1323.                      * before giving up. */
  1324. {
  1325.     /*
  1326.      * Timeout after waiting one second, poll every 100 microseconds.
  1327.      */
  1328.     for(; maxCount > 0; maxCount--) {
  1329.     if (*wordPtr & bit) {
  1330.         return (TRUE);
  1331.     }
  1332.     MACH_DELAY(100);
  1333.     }
  1334.     return ((*wordPtr & bit) != 0);
  1335. }
  1336.  
  1337.  
  1338. /*
  1339.  *----------------------------------------------------------------------
  1340.  *
  1341.  * CheckSizes --
  1342.  *
  1343.  *    Check the sizes of the Jaguar structure declarations to insure they
  1344.  *    are consistent with the controller's ideas.  This routine is 
  1345.  *    intended to catch padding introduced by the compiler that may 
  1346.  *    break the driver's code. This checking should really be done at
  1347.  *    compile time but run time checking is better nothing. 
  1348.  *
  1349.  * Results:
  1350.  *    TRUE if the sizes checked are ok, FALSE otherwise.
  1351.  *
  1352.  * Side effects:
  1353.  *    None.
  1354.  *
  1355.  *----------------------------------------------------------------------
  1356.  */
  1357.  
  1358. static Boolean
  1359. CheckSizes()
  1360. {
  1361.     return (
  1362.         (SIZE_JAUGAR_MEM == sizeof(JaguarMem)) &&
  1363.     (JAGUAR_MCSB_SIZE == sizeof(JaguarMCSB)) &&
  1364.     (JAGUAR_CQE_SIZE == sizeof(JaguarCQE)) &&
  1365.     (JAGUAR_CCSB_SIZE == sizeof(JaguarCCSB)) &&
  1366.     (JAGUAR_CIB_SIZE == sizeof(JaguarCIB)) &&
  1367.     (JAGUAR_MAX_IOBP_SIZE == sizeof(JaguarIOPB)) &&
  1368.     (JAGUAR_CRB_SIZE == (sizeof(JaguarCRB) - sizeof(JaguarIOPB))) &&
  1369.     (JAGUAR_SG_SIZE == sizeof(JaguarSG))
  1370.     );
  1371. }
  1372.  
  1373. /*
  1374.  *----------------------------------------------------------------------
  1375.  *
  1376.  * FillInScsiIOPB --
  1377.  *
  1378.  *    Fill in a Jaguar IOPB with a SCSI PASS-THRU command to send 
  1379.  *    the specified scsi command block to the specified device.
  1380.  *
  1381.  * Results:
  1382.  *    None.
  1383.  *
  1384.  * Side effects:
  1385.  *    None.
  1386.  *
  1387.  *----------------------------------------------------------------------
  1388.  */
  1389.  
  1390. static void
  1391. FillInScsiIOPB(devPtr, scsiCmdPtr, iopbPtr)
  1392.     Device    *devPtr;    /* Target device for command. */
  1393.     ScsiCmd    *scsiCmdPtr;    /* SCSI command being sent. */
  1394.     volatile JaguarIOPB    *iopbPtr;    /* IOPB to be filled in . */
  1395. {
  1396.     Address    addr;
  1397.     int        amod;
  1398.  
  1399.     bzero((char *)iopbPtr, sizeof(JaguarIOPB));
  1400.     iopbPtr->command = JAGUAR_PASS_THRU_CMD;
  1401.     iopbPtr->options = JAGUAR_IOPB_INTR_ENA | 
  1402.             (scsiCmdPtr->dataToDevice ? JAGUAR_IOPB_TO_HBA : 0);
  1403.     iopbPtr->intrVector =  devPtr->ctrlPtr->intrVector;
  1404.     iopbPtr->intrLevel = devPtr->ctrlPtr->intrLevel;
  1405.     if (VmMachIsXbusMem(scsiCmdPtr->buffer)) {
  1406.     amod = JAGUAR_BLOCK_ADDRESS_MODIFIER;
  1407.     addr = scsiCmdPtr->buffer;
  1408.     } else {
  1409.     amod = JAGUAR_WORD_ADDRESS_MODIFIER;
  1410.     if (scsiCmdPtr->bufferLen > 0) {
  1411.         /*
  1412.          * If the address is already in DMA space we do not have to
  1413.          * map it.  We set the lowest bit of the address to inform
  1414.          * the interrupt handler not to free it.
  1415.          */
  1416.         if (((unsigned)scsiCmdPtr->buffer)<(unsigned)VMMACH_DMA_START_ADDR){
  1417.         addr = VmMach_32BitDMAAlloc(scsiCmdPtr->bufferLen, 
  1418.                          scsiCmdPtr->buffer);
  1419.         } else {
  1420.         addr = (Address) (((unsigned) scsiCmdPtr->buffer) | 1);
  1421.         }
  1422.     } else {
  1423.         addr = (Address) VMMACH_DMA_START_ADDR;
  1424.     }
  1425.     if ((unsigned) addr >= (unsigned)VMMACH_DMA_START_ADDR) {
  1426.         addr -= VMMACH_DMA_START_ADDR;
  1427.     }
  1428.     }
  1429.     iopbPtr->addrModifier = amod;
  1430.     SET_LONG(iopbPtr->bufferAddr, (unsigned)addr);
  1431.     SET_LONG(iopbPtr->maxXferLen, scsiCmdPtr->bufferLen);
  1432.     iopbPtr->cmd.scsiArg.unitAddress = devPtr->unitAddress;
  1433.     bcopy(scsiCmdPtr->commandBlock, (char *) iopbPtr->cmd.scsiArg.cmd, 
  1434.                 scsiCmdPtr->commandBlockLen);
  1435. }
  1436.  
  1437.  
  1438. /*
  1439.  *----------------------------------------------------------------------
  1440.  *
  1441.  * ScsiErrorProc --
  1442.  *
  1443.  *    This function retrieves the Sense data from a device and 
  1444.  *    Unfreezes the queue to the device.
  1445.  *
  1446.  * Results:
  1447.  *    None.
  1448.  *
  1449.  * Side effects:
  1450.  *    A REQUEST SENSE command is sent to the device and the requesting
  1451.  *    call back function called.
  1452.  *
  1453.  *----------------------------------------------------------------------
  1454.  */
  1455. /*ARGSUSED*/
  1456. static void
  1457. ScsiErrorProc(data, callInfoPtr)
  1458.     ClientData          data;
  1459.     Proc_CallInfo       *callInfoPtr;
  1460. {
  1461.     Device    *devPtr = (Device *) data;
  1462.     volatile JaguarIOPB iopbMem;    
  1463.     JaguarCRB    crb;
  1464.     ScsiCmd    senseCmd;
  1465.     char    senseBuffer[DEV_MAX_SENSE_BYTES];
  1466.     DevScsiSenseCmd((ScsiDevice *)devPtr, DEV_MAX_SENSE_BYTES, senseBuffer, 
  1467.             &senseCmd);
  1468.     FillInScsiIOPB(devPtr, &senseCmd, &iopbMem);
  1469.     bzero((char *)&crb, sizeof(crb));
  1470.     MASTER_LOCK(&devPtr->ctrlPtr->mutex);
  1471.     (void) SendJaguarCmd(devPtr->ctrlPtr, 0, &iopbMem, FILL_IN_CRB_ACTION, 
  1472.               (ClientData) &crb);
  1473.     MASTER_UNLOCK(&devPtr->ctrlPtr->mutex);
  1474.     /*
  1475.      * Ignore the 0x34 ( transfer length mismatch) we're likely to get.
  1476.      */
  1477.     if (crb.iopb.returnStatus & 0xff) {
  1478.     crb.iopb.returnStatus &= ~0xff;
  1479.     }
  1480.     if (crb.iopb.returnStatus != 0) {
  1481.     (devPtr->frozen.scsiCmdPtr->doneProc)(devPtr->frozen.scsiCmdPtr, 
  1482.                    SUCCESS, devPtr->frozen.statusByte,
  1483.                    devPtr->frozen.amountTransferred,
  1484.                    0, (char *) 0);
  1485.     } else {
  1486.     (devPtr->frozen.scsiCmdPtr->doneProc)(devPtr->frozen.scsiCmdPtr, 
  1487.                    SUCCESS, devPtr->frozen.statusByte,
  1488.                    devPtr->frozen.amountTransferred,
  1489.                    READ_LONG(crb.iopb.maxXferLen), senseBuffer);
  1490.  
  1491.     }
  1492.     /*
  1493.      * Unfreze the workqueue for this device. 
  1494.      */
  1495.     MASTER_LOCK(&devPtr->ctrlPtr->mutex);
  1496.     devPtr->ctrlPtr->memPtr->mcsb.thawQueue = 
  1497.             THAW_WORK_QUEUE(devPtr->workQueue);
  1498.     MACH_DELAY(100);
  1499.     MASTER_UNLOCK(&devPtr->ctrlPtr->mutex);
  1500. }
  1501.  
  1502.  
  1503. /*
  1504.  *----------------------------------------------------------------------
  1505.  *
  1506.  * RequestDone --
  1507.  *
  1508.  *    Process a request that has finished. Unless a SCSI check condition
  1509.  *    bit is present in the status returned, the request call back
  1510.  *    function is called.  If check condition is set we fire off a
  1511.  *    SCSI REQUEST SENSE to get the error sense bytes from the device.
  1512.  *
  1513.  * Results:
  1514.  *    None.
  1515.  *
  1516.  * Side effects:
  1517.  *    The call back function may be called.
  1518.  *
  1519.  *----------------------------------------------------------------------
  1520.  */
  1521.  
  1522. static void
  1523. RequestDone(devPtr,scsiCmdPtr,status,scsiStatusByte,amountTransferred)
  1524.     Device    *devPtr;    /* Device for request. */
  1525.     ScsiCmd    *scsiCmdPtr;    /* Request that finished. */
  1526.     ReturnStatus status;    /* Status returned. */
  1527.     unsigned char scsiStatusByte;    /* SCSI Status Byte. */
  1528.     int        amountTransferred; /* Amount transferred by command. */
  1529. {
  1530.     if (devJaguarDebug > 3) {
  1531.     printf("RequestDone for %s status 0x%x scsistatus 0x%x count %d\n",
  1532.         devPtr->handle.locationName, status,scsiStatusByte,
  1533.         amountTransferred);
  1534.     }
  1535.     /*
  1536.      * If the request 
  1537.      * suffered an error or the HBA or the scsi status byte
  1538.      * says there is no error sense present, we can do the
  1539.      * callback and free the controller.
  1540.      */
  1541.     if ((status != SUCCESS) || !SCSI_CHECK_STATUS(scsiStatusByte)) {
  1542.     (scsiCmdPtr->doneProc)(scsiCmdPtr, status, scsiStatusByte,
  1543.                    amountTransferred, 0, (char *) 0);
  1544.      return;
  1545.    } 
  1546.    /*
  1547.     * If we got here than the SCSI command came back from the device
  1548.     * with the CHECK bit set in the status byte. We do this with 
  1549.     * a call back process that can wait for workQueue 0 to become
  1550.     * available.
  1551.     */
  1552.    devPtr->frozen.scsiCmdPtr = scsiCmdPtr;
  1553.    devPtr->frozen.statusByte = scsiStatusByte;
  1554.    devPtr->frozen.amountTransferred = amountTransferred;
  1555.    Proc_CallFunc(ScsiErrorProc, (ClientData) devPtr, 0);
  1556. }
  1557.  
  1558. /*
  1559.  *----------------------------------------------------------------------
  1560.  *
  1561.  * ReleaseProc --
  1562.  *
  1563.  *    Release an attached Jaguar device.
  1564.  *
  1565.  * Results:
  1566.  *    None.
  1567.  *
  1568.  * Side effects:
  1569.  *    None.
  1570.  *
  1571.  *----------------------------------------------------------------------
  1572.  */
  1573. /*ARGSUSED*/
  1574. static ReturnStatus
  1575. ReleaseProc(scsiDevicePtr)
  1576.     ScsiDevice    *scsiDevicePtr;
  1577. {
  1578.     return SUCCESS;
  1579. }
  1580.  
  1581.  
  1582.  
  1583. /*
  1584.  *----------------------------------------------------------------------
  1585.  *
  1586.  * entryAvailProc --
  1587.  *
  1588.  *    Act upon an entry becomming available in the queue for this
  1589.  *    controller. This routine is the Dev_Queue callback function that
  1590.  *    is called whenever work becomes available for this controller. 
  1591.  *    If the controller is not already busy we dequeue and start the
  1592.  *    request.
  1593.  *
  1594.  * Results:
  1595.  *    None.
  1596.  *
  1597.  * Side effects:
  1598.  *    Request may be dequeue and submitted to the device. Request callback
  1599.  *    function may be called.
  1600.  *
  1601.  *----------------------------------------------------------------------
  1602.  */
  1603.  
  1604. static Boolean
  1605. entryAvailProc(clientData, newRequestPtr) 
  1606.    ClientData    clientData;    /* Really the Device this request ready. */
  1607.    List_Links *newRequestPtr;    /* The new SCSI request. */
  1608. {
  1609.     register Device *devPtr = (Device *) clientData;
  1610.     register Controller *ctrlPtr = devPtr->ctrlPtr;
  1611.     register ScsiCmd    *scsiCmdPtr = (ScsiCmd *) newRequestPtr;
  1612.     Boolean    good;
  1613.  
  1614.  
  1615.     if (devPtr->numActiveCmds >= MAX_CMDS_QUEUED) { 
  1616.     return FALSE;
  1617.     }
  1618.     devPtr->numActiveCmds++;
  1619.     good = SendScsiCommand(devPtr, scsiCmdPtr);
  1620.     /*    
  1621.      * If the command couldn't be started do the callback function.
  1622.      */
  1623.     if (!good) {
  1624.      devPtr->numActiveCmds--;
  1625.      MASTER_UNLOCK(&(ctrlPtr->mutex));
  1626.      RequestDone(devPtr,scsiCmdPtr,(ReturnStatus)DEV_HARD_ERROR,0,0);
  1627.      MASTER_LOCK(&(ctrlPtr->mutex));
  1628.     }
  1629.     return TRUE;
  1630.  
  1631. }   
  1632.  
  1633. /*
  1634.  *----------------------------------------------------------------------
  1635.  *
  1636.  * StartNextRequest --
  1637.  *
  1638.  *    Start the next request on the device. 
  1639.  *
  1640.  * Results:
  1641.  *    None.
  1642.  *
  1643.  * Side effects:
  1644.  *    None.
  1645.  *
  1646.  *----------------------------------------------------------------------
  1647.  */
  1648.  
  1649. static void
  1650. StartNextRequest(devPtr)
  1651.     Device    *devPtr;    /* Device to start request on. */
  1652. {
  1653.     List_Links    *newRequest;
  1654.  
  1655.     while (devPtr->numActiveCmds < MAX_CMDS_QUEUED) { 
  1656.     newRequest = Dev_QueueGetNext(devPtr->handle.devQueue);
  1657.     if (newRequest == (List_Links *) NIL) {
  1658.         break;
  1659.     }
  1660.     (void) entryAvailProc((ClientData) devPtr, newRequest);
  1661.     }
  1662. }
  1663.  
  1664. /*
  1665.  *----------------------------------------------------------------------
  1666.  *
  1667.  * DevJaguarInit --
  1668.  *
  1669.  *    Check for the existant of the Jaguar HBA controller. If it
  1670.  *    exists allocate data stuctures for it.
  1671.  *
  1672.  * Results:
  1673.  *    TRUE if the controller exists, FALSE otherwise.
  1674.  *
  1675.  * Side effects:
  1676.  *    Memory may be allocated.
  1677.  *
  1678.  *----------------------------------------------------------------------
  1679.  */
  1680. ClientData
  1681. DevJaguarInit(ctrlLocPtr)
  1682.     DevConfigController    *ctrlLocPtr;    /* Controller location. */
  1683. {
  1684.     int    ctrlNum;
  1685.     Controller *ctrlPtr;
  1686.     short    x;
  1687.     int        i;
  1688.     Address    address;
  1689.     ReturnStatus status;
  1690.  
  1691.     /*
  1692.      * See if the controller is there. This controller should occupy
  1693.      * 2k in the short IO space of the VME.
  1694.      */
  1695.     if (ctrlLocPtr->space != DEV_VME_D16A16) {
  1696.     panic("Jaguar SCSI HBA %d configured in bad address space %d @ 0x%x\n",
  1697.           ctrlLocPtr->controllerID, ctrlLocPtr->space, ctrlLocPtr->address);
  1698.     return DEV_NO_CONTROLLER;
  1699.     }
  1700.  
  1701.     address =    (Address) ctrlLocPtr->address;
  1702.     status = Mach_Probe(sizeof(short), address, (char *)&x);
  1703.     if (status == SUCCESS) {
  1704.     status = Mach_Probe(sizeof(short), address + 2*1024 - 2,(char *)&x);
  1705.     }
  1706.     if (status != SUCCESS) {
  1707.     if (devJaguarDebug > 3) {
  1708.         printf("Jaguar # %d not found at address 0x%x\n",
  1709.            ctrlLocPtr->controllerID, address);
  1710.     }
  1711.     return DEV_NO_CONTROLLER;
  1712.     }
  1713.     if (!CheckSizes()) {
  1714.     panic("Jaguar driver structure layout broken\n");
  1715.     return DEV_NO_CONTROLLER;
  1716.     }
  1717.     ctrlNum = ctrlLocPtr->controllerID;
  1718.     { 
  1719.     Boolean    good;
  1720.     good = InitializeJaguar((volatile JaguarMem *) address,
  1721.                          ctrlLocPtr->name,
  1722.                  VME_INTERRUPT_PRIORITY,
  1723.                  ctrlLocPtr->vectorNumber);
  1724.     if (!good) {
  1725.         return DEV_NO_CONTROLLER;
  1726.     }
  1727.     }
  1728.     ctrlPtr = Controllers[ctrlNum] = (Controller *) malloc(sizeof(*ctrlPtr));
  1729.     bzero((char *) ctrlPtr, sizeof(Controller));
  1730.     ctrlPtr->memPtr = (JaguarMem *) address;
  1731.     ctrlPtr->nextCQE = ctrlPtr->memPtr->cmdQueue;
  1732.     ctrlPtr->workQueue0Busy = FALSE;
  1733.  
  1734.     ctrlPtr->name = ctrlLocPtr->name;
  1735.     Sync_SemInitDynamic(&(ctrlPtr->mutex),ctrlPtr->name);
  1736.     /* 
  1737.      * Initialized the name, device queue header, and the master lock.
  1738.      * The controller comes up with no devices active and no devices
  1739.      * attached.  
  1740.      */
  1741.     ctrlPtr->devQueues = Dev_CtrlQueuesCreate(&(ctrlPtr->mutex),entryAvailProc);
  1742.     ctrlPtr->intrLevel = VME_INTERRUPT_PRIORITY;
  1743.     /*
  1744.      * Use the same vector for both error and normal completion.
  1745.      */
  1746.     ctrlPtr->intrVector = 
  1747.     JAGUAR_IOPB_INTR_VECTOR(ctrlLocPtr->vectorNumber,
  1748.                 ctrlLocPtr->vectorNumber);
  1749.     for (i = 0; i < NUM_WORK_QUEUES; i++) {
  1750.     ctrlPtr->devices[i] = (Device *) NIL;
  1751.     }
  1752.  
  1753.     return (ClientData) ctrlPtr;
  1754. }
  1755.  
  1756.  
  1757. /*
  1758.  *----------------------------------------------------------------------
  1759.  *
  1760.  * DevJaguarAttachDevice --
  1761.  *
  1762.  *    Attach a SCSI device using the Jaguar HBA. 
  1763.  *
  1764.  * Results:
  1765.  *    None.
  1766.  *
  1767.  * Side effects:
  1768.  *    None.
  1769.  *
  1770.  *----------------------------------------------------------------------
  1771.  */
  1772.  
  1773. ScsiDevice   *
  1774. DevJaguarAttachDevice(devicePtr, insertProc)
  1775.     Fs_Device    *devicePtr;     /* Device to attach. */
  1776.     void (*insertProc) _ARGS_ ((List_Links *elementPtr,
  1777.                                 List_Links *elementListHdrPtr));
  1778.                                  /* Queue insert procedure. */
  1779. {
  1780.     Device *devPtr;
  1781.     Controller    *ctrlPtr;
  1782.     char   tmpBuffer[512];
  1783.     int       ctrlNum;
  1784.     int       targetID, lun, bus;
  1785.     int       i, workQueue;
  1786.  
  1787.     /*
  1788.      * First find the Jaguar controller this device is on. For the Jaguar
  1789.      * we really have 2 HBA per real controller because each HBA has 
  1790.      * two SCSI buses.
  1791.      */
  1792.     ctrlNum = SCSI_HBA_NUMBER(devicePtr)/2;
  1793.     if ((ctrlNum > MAX_JAGUAR_CTRLS) ||
  1794.     (Controllers[ctrlNum] == (Controller *) 0)) { 
  1795.     return (ScsiDevice  *) NIL;
  1796.     } 
  1797.     ctrlPtr = Controllers[ctrlNum];
  1798.     /*
  1799.      * See if the device is already present.
  1800.      */
  1801.     targetID = SCSI_TARGET_ID(devicePtr);
  1802.     lun = SCSI_LUN(devicePtr);
  1803.     bus = SCSI_HBA_NUMBER(devicePtr) & 0x1;
  1804.     MASTER_LOCK(&(ctrlPtr->mutex));
  1805.     /*
  1806.      * See if we already have a work queue setup for this device. Also,
  1807.      * find a unsed workQueue to allocate for this device.
  1808.      */
  1809.     workQueue = -1;
  1810.     for (i = 0; i < NUM_WORK_QUEUES; i++) {
  1811.     if (ctrlPtr->devices[i] != (Device *) NIL) {
  1812.         if ((ctrlPtr->devices[i]->targetID == targetID) &&
  1813.             (ctrlPtr->devices[i]->bus == bus)) {
  1814.         if (ctrlPtr->devices[i]->handle.LUN == lun) {
  1815.             MASTER_UNLOCK(&(ctrlPtr->mutex));
  1816.             return (ScsiDevice  *) (ctrlPtr->devices[i]);
  1817.         }
  1818.         /*
  1819.          * The same targetID and a different LUN doesn't work.
  1820.          */
  1821.         MASTER_UNLOCK(&(ctrlPtr->mutex));
  1822.         printf("Warning: %s: 4210 only supports one LUN per target.\n",
  1823.                ctrlPtr->name);
  1824.         printf("%s: Target %d LUN %d is already present.\n", 
  1825.               ctrlPtr->name,
  1826.               ctrlPtr->devices[i]->targetID, 
  1827.               ctrlPtr->devices[i]->handle.LUN);
  1828.         return (ScsiDevice *) NIL;
  1829.         }
  1830.     } else {
  1831.         /*
  1832.          * Record the first unsed workQueue.
  1833.          */
  1834.         if (workQueue == -1) {
  1835.         workQueue = i+1;
  1836.         }
  1837.     }
  1838.     }
  1839.     MASTER_UNLOCK(&(ctrlPtr->mutex));
  1840.     if (workQueue == -1) {
  1841.     printf("%s: Too many devices attached.\n", ctrlPtr->name);
  1842.     return (ScsiDevice *) NIL;
  1843.     }
  1844.  
  1845.     if (!InitializeWorkq(ctrlPtr, workQueue, FALSE, 1)) {
  1846.     return (ScsiDevice *) NIL;
  1847.     }
  1848.  
  1849.     ctrlPtr->devices[workQueue-1] = devPtr =
  1850.                     (Device *) malloc(sizeof(Device));
  1851.     bzero((char *) devPtr, sizeof(Device));
  1852.     devPtr->handle.devQueue = Dev_QueueCreate(ctrlPtr->devQueues,
  1853.                 0, insertProc, (ClientData) devPtr);
  1854.     (void) sprintf(tmpBuffer, "%s Bus %d Target %d LUN %d", ctrlPtr->name, 
  1855.              bus, targetID, lun);
  1856.     devPtr->handle.locationName = 
  1857.         (char *) strcpy(malloc(strlen(tmpBuffer)+1),tmpBuffer);
  1858.     devPtr->handle.LUN = lun;
  1859.     devPtr->handle.releaseProc = ReleaseProc;
  1860.     devPtr->handle.maxTransferSize = DEV_MAX_DMA_SIZE;
  1861.  
  1862.     devPtr->bus = bus;
  1863.     devPtr->targetID = targetID;
  1864.     devPtr->unitAddress = JAGUAR_UNIT_ADDRESS(bus, targetID, lun);
  1865.     devPtr->workQueue = workQueue;
  1866.     devPtr->ctrlPtr = ctrlPtr;
  1867.     return (ScsiDevice *) devPtr;
  1868. }
  1869.  
  1870.